package org.zhxy.zhxy.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.zhxy.zhxy.entity.Admin;
import org.zhxy.zhxy.entity.dto.AdminForgetDto;
import org.zhxy.zhxy.entity.dto.AdminLoginDto;
import org.zhxy.zhxy.service.AdminService;
import org.zhxy.zhxy.service.LoginService;
import org.zhxy.zhxy.utils.MD5Utils;
import org.zhxy.zhxy.utils.RedisConstants;
import org.zhxy.zhxy.utils.Result;
import org.zhxy.zhxy.utils.SendEmailUtil;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;


/**
 * 后台管理登录service实现类
 *
 * @author pxx
 */
@Service
@Slf4j
public class LoginServiceImpl implements LoginService {

    @Autowired
    private AdminService adminService;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private SendEmailUtil sendEmailUtil;

    /**
     * 账号密码登录
     *
     * @param adminLoginDto 后台登录dto
     * @return
     */
    @Override
    public Result byPwd(AdminLoginDto adminLoginDto) {
        String username = adminLoginDto.getUsername();
        String password = adminLoginDto.getPassword();
        if (StrUtil.isBlank(username)) {
            return Result.fail("账号不能为空");
        }

        if (StrUtil.isBlank(password)) {
            return Result.fail("密码不能为空");
        }

        String encodePwd = MD5Utils.encodeByMd5(password);
        Admin admin = adminService.getByUsernameAndPwd(username, encodePwd);
        if (ObjectUtil.isNull(admin)) {
            return Result.fail("账号不存在或密码错误");
        }

        Map<String, String> adminData = new HashMap<>();
        adminData.put("id", String.valueOf(admin.getId()));
        adminData.put("username", admin.getUsername());
        adminData.put("image", admin.getImage());
        adminData.put("email", admin.getEmail());
        String token = UUID.randomUUID().toString();
        adminData.put("token", token);
        adminData.put("createTime", DateUtil.format(admin.getCreateTime(), "YYYY年MM月dd日 hh:mm:ss"));
        adminData.put("updateTime", DateUtil.format(admin.getUpdateTime(), "YYYY年MM月dd日 hh:mm:ss"));

        // 将管理员信息存入redis
        stringRedisTemplate.opsForHash().putAll(RedisConstants.LOGIN_TOKEN + token, adminData);
        // 设置过期时间
        stringRedisTemplate.expire(RedisConstants.LOGIN_TOKEN + token, RedisConstants.LOGIN_TOKEN_TTL, TimeUnit.HOURS);
        log.info("登录成功,{}", adminLoginDto);
        return Result.success(adminData);
    }

    /**
     * 忘记密码
     *
     * @param adminForgetDto
     * @return
     */
    @Override
    public Result forgetPwd(AdminForgetDto adminForgetDto) {
        String email = adminForgetDto.getEmail();
        String password = adminForgetDto.getPassword();
        String code = adminForgetDto.getCode();
        if (StrUtil.isBlank(email)) {
            return Result.fail("邮箱不能为空");
        }
        if (StrUtil.isBlank(password)) {
            return Result.fail("新密码不能为空");
        }
        if (StrUtil.isBlank(code)) {
            return Result.fail("验证码不能为空");
        }
        String redisKey = RedisConstants.ADMIN_CODE + email;
        String redisCode = stringRedisTemplate.opsForValue().get(redisKey);
        if (StrUtil.isBlank(redisCode)) {
            return Result.fail("验证码已过期");
        }
        if (!code.equals(redisCode)) {
            return Result.fail("验证码不正确");
        }
        stringRedisTemplate.delete(redisKey);
        // 修改用户密码
        String encodePwd = MD5Utils.encodeByMd5(password);
        int i = adminService.forgetPwd(email, encodePwd);
        if (i <= 0) {
            return Result.fail("密码修改失败");
        }
        return Result.success("密码修改成功");
    }

    /**
     * 发送验证码
     *
     * @param email
     * @return
     */
    @Override
    public Result sendCode(String email) {
       /* Admin admin = adminService.getByEmail(email);
        if (ObjectUtil.isNull(admin)) {
            return Result.fail("该邮箱未绑定有任何账号");
        }*/
        String redisKey = RedisConstants.ADMIN_CODE + email;
        // 查询redis中是否已经存在验证码
        String redisCode = stringRedisTemplate.opsForValue().get(redisKey);
        if (StrUtil.isNotBlank(redisCode)) {
            return Result.fail("验证码已存在，请勿重复发送");
        }

        //生成codeLength位随机验证码
        String code = RandomUtil.randomNumbers(6);
        log.info("生成的验证码：{}",code);
        sendEmailUtil.sendEmail("chpincp@qq.com", email, "智慧校园后台管理-验证码",
                "验证码：" + code + "。此验证码用于智慧校园后台管理，有效期为" + RedisConstants.ADMIN_CODE_TTL + "分钟！");
        //在redis设置验证码和失效时间
        stringRedisTemplate.opsForValue().set(redisKey, code, RedisConstants.ADMIN_CODE_TTL, TimeUnit.MINUTES);
        return Result.success("验证码发送成功");
    }
}
